/*
 *   Copyright (c) 2018. 刘路 All rights reserved
 *   版权所有 刘路 并保留所有权利 2018.
 *   ===============================================================
 *   这不是一个自由软件！您只能在不用于商业目的的前提下对程序代码进行修改和
 *   使用。不允许对程序代码以任何形式任何目的的再发布。如果项目发布携带作者
 *   认可的特殊 LICENSE 则按照 LICENSE 执行，废除上面内容。请保留原作者信息。
 *   ================================================================
 *   刘路（feedback@zhoyq.com）于 2018. 创建
 *   http://zhoyq.com
 */

package com.zhoyq.helper;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * //使用JavaMail发送邮件的5个步骤
 * //1、创建session
 * //   开启Session的debug模式，这样就可以查看到程序发送Email的运行状态
 * //2、通过session得到transport对象
 * //3、连上邮件服务器，需要发件人提供邮箱的用户名和密码进行验证
 * //4、创建邮件
 * //5、发送邮件
 * e.

 String path = "C:/04a410d0fc558fc346ee572a42bb96d3.jpg";
 File file = new File(path);
 Map<String,File> pics = new HashMap<String, File>();
 pics.put("xxx.jpg", file);
 List<File> files = new ArrayList<File>();
 files.add(file);
 // sendText("xxx@qq.com","标题","内容");
 // sendImage("xxx@qq.com","标题","内容<br><img src='cid:xxx.jpg'>", pics);
 // sendAttach("xxx@qq.com","标题","内容", files);
 // sendMixed("xxx@qq.com","标题","内容<br><img src='cid:xxx.jpg'>", pics, files);

 * @author 刘路
 */
public class MailHelper {

  public final static String MAIL_HOST = "";
  public final static String MAIL_PROTOCOL = "smtp";
  public final static String MAIL_AUTH = "true";
  public final static String MAIL_ADDR = "";
  public final static String MAIL_PASS = "";
  
  private static Transport transport(Session session){
    try {
      Transport ts = session.getTransport();
      return ts;
    } catch (NoSuchProviderException e) {
      return null;
    }
  } 
  private static Address[] addrs(String[] str) throws AddressException{
    InternetAddress[] res = new InternetAddress[str.length];
    for(int i=0;i<str.length;i++){
      res[i] = new InternetAddress(str[i]);
    }
    return res;
  }
  
  private static Session session(boolean debug){
    Properties prop = new Properties();
    prop.setProperty("mail.host", MAIL_HOST);
    prop.setProperty("mail.transport.protocol", MAIL_PROTOCOL);
    prop.setProperty("mail.smtp.auth", MAIL_AUTH);
    Session session = Session.getInstance(prop);
    session.setDebug(debug);
    return session;
  } 
  
  private static void setReceiver(MimeMessage message,String[] addrs) throws MessagingException{
    List<Address> toList = new ArrayList<Address>();
    List<Address> ccList = new ArrayList<Address>();
    List<Address> bccList = new ArrayList<Address>();
    for(int i = 0;i<addrs.length;i++){
      String addr = addrs[i];
      String addrbuf = addr.substring(addr.indexOf(":")+1);
      if(addr.startsWith("TO:")){
        // 直接发送
        toList.add(new InternetAddress(addrbuf));
      }else if(addr.startsWith("CC:")){
        // 抄送
        ccList.add(new InternetAddress(addrbuf));
      }else if(addr.startsWith("BCC:")){
        // 密送
        bccList.add(new InternetAddress(addrbuf));
      }
    }
    Address[] to = null,cc = null,bcc = null;
    if(toList.size()!=0) {
      to = new Address[toList.size()]; 
      for(int i=0;i<toList.size();i++){
        to[i] = toList.get(i);
      }
    }
    if(ccList.size()!=0) {
      cc = new InternetAddress[ccList.size()];
      for(int i=0;i<ccList.size();i++){
        cc[i] = ccList.get(i);
      }
    }
    if(bccList.size()!=0) {
      bcc = new InternetAddress[bccList.size()];
      for(int i=0;i<bccList.size();i++){
        bcc[i] = bccList.get(i);
      }
    }
    if(to!=null)  {
      message.setRecipients(Message.RecipientType.TO, to);
    }
    if(cc!=null)  {
      message.setRecipients(Message.RecipientType.CC, cc);
    }
    if(bcc!=null) {
      message.setRecipients(Message.RecipientType.BCC, bcc);
    }
  }
  
  public static boolean sendText(String[] addrs,String title,String content){
    Session session = session(false);
    Transport ts = transport(session);
    if(ts==null) {
      return false;
    }
    try {
      ts.connect( MAIL_HOST, MAIL_ADDR, MAIL_PASS);
      Message message = createTextMail(session,addrs,title,content);
      ts.sendMessage(message, message.getAllRecipients());
      ts.close();
      return true;
    } catch (Exception e) {
      return false;
    }
  } 
  public static boolean sendImage(String[] addrs,String title,String content,Map<String,File> pics){
    Session session = session(false);
    Transport ts = transport(session);
    if(ts==null) {
      return false;
    }
    try {
      ts.connect( MAIL_HOST, MAIL_ADDR, MAIL_PASS);
      Message message = createImageMail(session,addrs,title,content,pics);
      ts.sendMessage(message, message.getAllRecipients());
      ts.close();
      return true;
    } catch (Exception e) {
      return false;
    }
  } 
  public static boolean sendAttach(String[] addrs,String title,String content,List<File> files){
    Session session = session(false);
    Transport ts = transport(session);
    if(ts==null) {
      return false;
    }
    try {
      ts.connect( MAIL_HOST, MAIL_ADDR, MAIL_PASS);
      Message message = createAttachMail(session,addrs,title,content,files);
      ts.sendMessage(message, message.getAllRecipients());
      ts.close();
      return true;
    } catch (Exception e) {
      return false;
    }
  } 
  public static boolean sendMixed(String[] addrs,String title,String content,Map<String,File> pics,List<File> files){
    Session session = session(false);
    Transport ts = transport(session);
    if(ts==null) {
      return false;
    }
    try {
      ts.connect( MAIL_HOST, MAIL_ADDR, MAIL_PASS);
      Message message = createMixedMail(session,addrs,title,content,pics,files);
      ts.sendMessage(message, message.getAllRecipients());
      ts.close();
      return true;
    } catch (Exception e) {
      return false;
    }
  } 
  
  //文本邮件
  public static MimeMessage createTextMail(Session session,String[] addrs,String title,String content) throws AddressException, MessagingException {
    MimeMessage message = new MimeMessage(session);
    message.setFrom(new InternetAddress( MAIL_ADDR));
    setReceiver(message,addrs);
    message.setSubject(title);
    message.setContent(content, "text/html;charset=UTF-8");
    return message;
  }
  /**
   * 图片邮件
   * @param session
   * @param addrs
   * @param title
   * @param content
   * @return
   * @throws AddressException
   * @throws MessagingException
   */
  public static MimeMessage createImageMail(Session session,String[] addrs,String title,String content,Map<String,File> pics) throws AddressException, MessagingException {
    MimeMessage message = new MimeMessage(session);
    message.setFrom(new InternetAddress( MAIL_ADDR));
    setReceiver(message,addrs);
    message.setSubject(title);
    MimeBodyPart text = new MimeBodyPart();
    text.setContent(content, "text/html;charset=UTF-8");
    MimeMultipart mm = new MimeMultipart();
    mm.setSubType("related");
    for(String key:pics.keySet()){
      // 准备图片数据
      MimeBodyPart image = new MimeBodyPart();
      DataHandler dh = new DataHandler(new FileDataSource(pics.get(key)));
      image.setDataHandler(dh);
      image.setContentID(key);
      // 描述数据关系
      mm.addBodyPart(text);
      mm.addBodyPart(image);
    } 
    message.setContent(mm);
    message.saveChanges();
    return message;
  }
  //附件邮件
  public static MimeMessage createAttachMail(Session session,String[] addrs,String title,String content,List<File> files) throws AddressException, MessagingException {
    MimeMessage message = new MimeMessage(session); 
    message.setFrom(new InternetAddress( MAIL_ADDR));
    setReceiver(message,addrs);
    message.setSubject(title);
    MimeBodyPart text = new MimeBodyPart();
    text.setContent(content, "text/html;charset=UTF-8");
    
    MimeMultipart mp = new MimeMultipart();
    mp.setSubType("mixed");
    for(File file:files){
      //创建邮件附件
      MimeBodyPart attach = new MimeBodyPart();
      DataHandler dh = new DataHandler(new FileDataSource(file));
      attach.setDataHandler(dh);
      attach.setFileName(dh.getName());   
      
      //创建容器描述数据关系
      mp.addBodyPart(text);
      mp.addBodyPart(attach);
    }
    message.setContent(mp);
    message.saveChanges();
    // 返回生成的邮件
    return message;
  }
  //图片+附件邮件
  public static MimeMessage createMixedMail(Session session,String[] addrs,String title,String content,Map<String,File> pics,List<File> files) throws AddressException, MessagingException, UnsupportedEncodingException {
    MimeMessage message = new MimeMessage(session);
    message.setFrom(new InternetAddress( MAIL_ADDR));
    setReceiver(message,addrs);
    message.setSubject(title);
    
    //正文
    MimeBodyPart text = new MimeBodyPart();
    text.setContent(content,"text/html;charset=UTF-8");
       
    //描述关系:正文和图片
    MimeMultipart mp1 = new MimeMultipart();
    mp1.setSubType("related");
    
    for(String key:pics.keySet()){
      //图片
      MimeBodyPart image = new MimeBodyPart();
      image.setDataHandler(new DataHandler(new FileDataSource(pics.get(key))));
      image.setContentID(key);
      
      mp1.addBodyPart(text);
      mp1.addBodyPart(image);
    }
     
    //描述关系:正文和附件
    MimeMultipart mp2 = new MimeMultipart();
    mp2.setSubType("mixed");
    
    for(File file:files){
      //附件
      MimeBodyPart attach = new MimeBodyPart();
      DataHandler dh = new DataHandler(new FileDataSource(file));
      attach.setDataHandler(dh);
      attach.setFileName(MimeUtility.encodeText(dh.getName()));
      
      mp2.addBodyPart(attach);
    } 
    
    //代表正文的bodypart
    MimeBodyPart mbp = new MimeBodyPart();
    mbp.setContent(mp1);
    mp2.addBodyPart(mbp);
     
    message.setContent(mp2);
    message.saveChanges();
    return message;
  }
  
}
